//=====================================================================
//    COPYRIGHT(C) Innobeam
//    ALL RIGHTS RESERVED
//=====================================================================
//Filename    : LCD_DISPLAYON.v
//Created On  : 2019-12-09
//Author      : haoyu.xiao
//Description : exit standby
//Include     : 
//Modification: 
//=====================================================================
`timescale	1ns/100ps
`include	"../rtl/def_command.v"
module LCD_DISPLAYOFF(
	iClk,
	iRst_n,
	
	ovLCD_SPI_TxData,
	oLCD_SPI_Start,
	oLCD_DC,
	ivLCD_SPI_RxData,
	iLCD_SPI_Done,
		
	iLCD_Start_DisplayOff,
	oLCD_DisplayOff_Done
	);
	
//========================================================================
//    parameter
//========================================================================
//command
	parameter		LCD_SLEEP_OUT = `LCD_SLEEP_OUT;
	parameter		LCD_DISPLAY_ON = `LCD_DISPLAY_ON;
	parameter		LCD_DISPLAY_OFF = `LCD_DISPLAY_OFF;

//========================================================================
//    port
//========================================================================	
	input					iClk;
	input					iRst_n;
	
	output		[7:0]		ovLCD_SPI_TxData;
	output					oLCD_SPI_Start;
	output					oLCD_DC;
	input		[7:0]		ivLCD_SPI_RxData;
	input					iLCD_SPI_Done;
		
	input					iLCD_Start_DisplayOff;
	output					oLCD_DisplayOff_Done;
//========================================================================
//    signal
//========================================================================
	reg					rLCD_SPI_Start;
	reg					rLCD_DC;
	reg		[7:0]		rvLCD_SPI_TxData;
	reg					rLCD_DisplayOff_Done;
	reg		[7:0]		rvState;
	wire				wWait20msDone;
//========================================================================
	assign 				oLCD_SPI_Start = rLCD_SPI_Start;
	assign 				oLCD_DisplayOff_Done = rLCD_DisplayOff_Done;
	assign 				oLCD_DC = rLCD_DC;
	assign				ovLCD_SPI_TxData = rvLCD_SPI_TxData;

//========================================================================
	//FSM
	always@(posedge iClk or negedge iRst_n)begin
			if(!iRst_n)begin	
				rLCD_SPI_Start		<= 1'b0;
				rLCD_DC				<= 1'b0;
				rvLCD_SPI_TxData 	<= 8'h0;
				rLCD_DisplayOff_Done	<= 1'b0;
				rvState				<= 8'h0;
				end
			else begin
				case (rvState)
				//waiting for initialization
					8'd0: begin			
						rLCD_SPI_Start		<= 1'b0;
						rLCD_DC				<= 1'b0;
						rvLCD_SPI_TxData 	<= 8'h0;					
						rLCD_DisplayOff_Done <= 1'b0;					
						if (iLCD_Start_DisplayOff) begin		
							rvState <= 8'h1;
							end
						end
					//LCD software reset and delay 20ms
					8'd1: begin	
						rLCD_SPI_Start <= 1'b1;
						rLCD_DC	<= 1'b0;
						rvLCD_SPI_TxData <= LCD_SLEEP_OUT;
						rLCD_DisplayOff_Done <= 1'b0;
						rvState	<= rvState + 1'd1;						
						end	
					//wait 1 more clk to let spi master pull Done signal down.
					8'd2: begin
						rLCD_SPI_Start <= 1'b0;
						rLCD_DC	<= rLCD_DC;
						rvLCD_SPI_TxData <= rvLCD_SPI_TxData;
						rLCD_DisplayOff_Done <= 1'b0;
						if(iLCD_SPI_Done == 1'b1)begin
							rvState	<= rvState + 1'd1;
						end	
						end
					 8'd3: begin
						rLCD_SPI_Start <= 1'b1;
						rLCD_DC	<= 1'b0;
						rvLCD_SPI_TxData <= LCD_DISPLAY_OFF;		
						rLCD_DisplayOff_Done <= 1'b0;	
						rvState	<= rvState + 1'd1;				
						end	
					8'd4: begin
						rLCD_SPI_Start <= 1'b0;
						rLCD_DC	<= rLCD_DC;
						rvLCD_SPI_TxData <= rvLCD_SPI_TxData;		
						if(iLCD_SPI_Done == 1'b1)begin
							rvState	<= 8'h0;
							rLCD_DisplayOff_Done <= 1'b1;
						end					
						end	
					default:begin
						rLCD_SPI_Start <= 1'b0;
						rLCD_DC	<= 1'b0;
						rvLCD_SPI_TxData <= 8'h0;
						rLCD_DisplayOff_Done <= 1'b0;	
						rvState	<= 8'h0;		
						end
					endcase
				end
			end

endmodule